#pragma once
#ifndef __LIT__EXCEPTIONS__HH__
#define __LIT__EXCEPTIONS__HH__

#include <exception>
#include <LitString.h>
#include <LitExceptionTypes.h>

namespace Lit
{
	struct LIT_API Exception
	{
		Exception( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) ;
		Exception( const Exception& rk );
		virtual ~Exception( );

		std::string location() const;
		std::string error() const;
		
		void _buildFull();

		const std::string &full() const;

		virtual const char * what() const;

		ExceptionType type() const;
		int line() const;
		const std::string& file() const;
		const std::string& message() const;
		const std::string& function() const;

	protected:
		ExceptionType	mType;
		int				mLine;
		std::string		mFile;
		std::string		mMessage;
		std::string		mFunc;

		std::string		mFull;
	};
	struct LIT_API RuntimeError : public Exception, public std::runtime_error
	{
		RuntimeError( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) ;
		RuntimeError( const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) ;
		RuntimeError( const RuntimeError & rk  ) ;
		virtual ~RuntimeError( );

		const char* what() const{ return Exception::what(); }

	};
	struct LIT_API LogicError : public Exception, public std::logic_error
	{
	public:
		LogicError( ExceptionType type, const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) ;
		LogicError( const std::string &_msg, const std::string &func_, int _line, const std::string &_file ) ;
		LogicError( const LogicError & rk );
		virtual ~LogicError( );

		const char* what() const{ return Exception::what(); }

	};

	struct LIT_API NullPointer				: public RuntimeError{NullPointer( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) ;};
	struct LIT_API CastError				: public LogicError	{CastError( const std::string &varname, const std::string &from, const std::string &to, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API ImplementationMissing	: public LogicError	{ImplementationMissing( const std::string &func_name, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API IOError					: public RuntimeError{IOError( const std::string &filename, const std::string& desc, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API InitialisationError		: public LogicError	{InitialisationError( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API ShutdownError			: public LogicError	{ShutdownError( const std::string &msg, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API InvalidPath				: public RuntimeError{InvalidPath( const std::string &path, bool directory, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API InvalidParameter			: public LogicError	{InvalidParameter( const std::string &param, const std::string &reason, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API MissingParameter			: public LogicError	{MissingParameter( const std::string &param, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API ItemMissing				: public LogicError	{std::string item;ItemMissing( const std::string &item, const std::string &item_mgr_name, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API ItemDuplicate			: public LogicError	{std::string item;ItemDuplicate( const std::string &item, const std::string &item_mgr_name, const std::string &func_, int _line, const std::string &_file ) ;	};
	struct LIT_API FileMissing				: public RuntimeError{std::string filename;FileMissing( const std::string &filename, const std::string &func, int line, const std::string &file );	};
	struct LIT_API FileDuplicate			: public RuntimeError{std::string filename;FileDuplicate( const std::string &filename, const std::string &func, int line, const std::string &file );	};
	struct LIT_API ModuleException			: public RuntimeError{std::string moduleName;ModuleException( const std::string &module, const std::string& error, const std::string &_func , int _line, const std::string &_file );	};
	struct LIT_API ConsoleError				: public RuntimeError{ConsoleError( const std::string &desc, const std::string &func = "", size_t line = 0, const std::string& file="" );	};
	struct LIT_API ConsoleTerminateError	: public RuntimeError{ConsoleTerminateError( const std::string &msg, const std::string &func="", size_t line=0, const std::string& file="" );	};
};

#define EXC_LOC __FUNCTION__, __LINE__, __FILE__

#endif